/*
 * main.m
 * 
 * Copyright (c) 2009 nathulal <inathulal at gmail.com>. All rights reserved.
 * Credits also due to rbisconti97 (xsellize dot com) for his research on the
 * Celestical.framework plist files
 * 
 * This file is part of SBSilentToggle.
 * 
 * SBSilentToggle is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * SBSilentToggle is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with SBSilentToggle.  If not, see <http://www.gnu.org/licenses/>.
 */
 
#import "substrate.h"
#include <notify.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <SpringBoard/SpringBoard.h>
#import <SpringBoard/SBStatusBarController.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>

static Class $SBStatusBarController;

// Determines if the device is capable of running on this platform. If your toggle is device specific like only for
// 3g you would check that here.
BOOL isCapable()
{
	return YES;
}

// This runs when iPhone springboard resets. This is on boot or respring.
BOOL isEnabled()
{
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSString *tempAdBlockFile = @"/var/mobile/Library/SBSettings/Toggles/Silent/SilentToggle.pid";
	if([fileManager fileExistsAtPath:tempAdBlockFile])
	{
		return YES;
	}
	return NO;
}

// This function is optional and should only be used if it is likely for the toggle to become out of sync
// with the state while the iPhone is running. It must be very fast or you will slow down the animated
// showing of the sbsettings window. Imagine 12 slow toggles trying to refresh tate on show.
BOOL getStateFast()
{
	BOOL retVal = isEnabled();
	if(retVal)
	{
		[[$SBStatusBarController sharedStatusBarController] addStatusBarItem:@"SILENTTOGGLE"];
	}
	else
	{
		[[$SBStatusBarController sharedStatusBarController] removeStatusBarItem:@"SILENTTOGGLE"];
	}
	return retVal;
}

// Pass in state to set. YES for enable, NO to disable.
void setState(BOOL Enable)
{
	SpringBoard * sb = (SpringBoard*) [UIApplication sharedApplication];
	if(sb != nil)
	{
		if(isEnabled())
		{
			[sb ringerChanged:1];
			[[$SBStatusBarController sharedStatusBarController] removeStatusBarItem:@"SILENTTOGGLE"];
		}
		else
		{
			[sb ringerChanged:0];
			[[$SBStatusBarController sharedStatusBarController] addStatusBarItem:@"SILENTTOGGLE"];
		}		
	}
	notify_post("com.nathulal.SBSilentToggle");
	//[NSThread sleepForTimeInterval:2.0];
}

// Amount of time spinner should spin in seconds after the toggle is selected.
float getDelayTime()
{
	return 0.7f;
}

@interface MyBGWorker : UIViewController 
+ (void) startTheBackgroundJob;
@end

@implementation MyBGWorker : UIViewController 

+ (void) startTheBackgroundJob {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
	// wait for 3 seconds before starting the thread, you don't have to do that. This is just an example how to stop the NSThread for some time  
	[NSThread sleepForTimeInterval:3];  
	SpringBoard * sb = (SpringBoard*) [UIApplication sharedApplication];
	while(sb == nil)
	{
		NSLog(@"SILENTTOGGLE:SpringBoard is nil. Waiting ...");
		[NSThread sleepForTimeInterval:3];
		sb = (SpringBoard*) [UIApplication sharedApplication];
	}
	if(isEnabled())
	{
		NSLog(@"SilentToggle is set to Vibrate.");
		[sb addStatusBarImageNamed:@"SILENTTOGGLE"]; 
	}
	[pool release];
}

@end 

// Runs when the dylib is loaded. Only useful for debug. Function can be omitted.
__attribute__((constructor)) 
static void toggle_initializer() 
{ 
	NSLog(@"Initializing SBSilent Toggle\n"); 
	$SBStatusBarController = objc_getClass("SBStatusBarController");
	[NSThread detachNewThreadSelector:@selector(startTheBackgroundJob) toTarget:[MyBGWorker class] withObject:nil];  
}